﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Windows.Media.TextFormatting;
using System.Windows.Threading;
using RiskMan.Config;
using RiskMan.DataClass.Models.Gilevskiy;

namespace RiskMan.Views.Gilevskiy
{

    /// <summary>
    /// Формирвоание и обработка таймфреймов
    /// </summary>
    public class TransformTimeFrames
    {
        private readonly MainWindow mainWindow = MainWindow.StaticLevel;
        private readonly DispatcherTimer _dsTimer = new DispatcherTimer();
        public static int NumberRowAllTrades = 0;


        /// <summary>
        /// Подписка на обработку событий каждую секунду
        /// </summary>
        public void TransformTimeFrameStart()
        {
            _dsTimer.Interval = TimeSpan.FromMilliseconds(1000);
            _dsTimer.Start();
            _dsTimer.Tick += new EventHandler(_dsTimer_Tick);
        }

        public void _dsTimer_Tick(Object sender, EventArgs args)
        {
            if (mainWindow._dataProvider.TimeFrameItems.Count > 0)
            {
                Logik();
            }
        }


        /// <summary>
        /// Логика формаирования таймфреймов
        /// </summary>
        public void Logik()
        {
            if (mainWindow._dataProvider.AllTradesList.Count > 0 && mainWindow._dataProvider.AllTradesList.Count > NumberRowAllTrades)
            {



                //формируем однаминутки по все заданным инструментам
                foreach (var item in mainWindow._dataProvider.TimeFrameItems)
                {
                    if (item.LastNumberDeal > mainWindow._dataProvider.AllTradesList.Count)
                        item.LastNumberDeal = 0;

                    #region работа с однаминутками
                    if (item.TimeFrame == 1)
                    {
                        for (int i = item.LastNumberDeal; i < mainWindow._dataProvider.AllTradesList.Count; i++)
                        {
                            if (item.Instrument == mainWindow._dataProvider.AllTradesList[i].Seccode)
                                if (item.CandleItems.Count > 0)
                                {
                                    var candle = item.CandleItems[item.CandleItems.Count - 1];

                                    if (candle.TradeDateTime.Date <=
                                        mainWindow._dataProvider.AllTradesList[i].TradeDate.Date &&
                                        Math.Abs(candle.TradeDateTime.TimeOfDay.TotalMinutes -
                                                 mainWindow._dataProvider.AllTradesList[i].TradeTime.TimeOfDay
                                                     .TotalMinutes) < 1)
                                    {
                                        candle.Close = mainWindow._dataProvider.AllTradesList[i].Price;
                                        if (candle.Low > mainWindow._dataProvider.AllTradesList[i].Price)
                                            candle.Low = mainWindow._dataProvider.AllTradesList[i].Price;
                                        if (candle.High < mainWindow._dataProvider.AllTradesList[i].Price)
                                            candle.High = mainWindow._dataProvider.AllTradesList[i].Price;
                                        candle.Volume = candle.Volume + mainWindow._dataProvider.AllTradesList[i].Quantity;
                                       // Cfg.SetLog(mainWindow._dataProvider.AllTradesList[i].TradeNum + " " + mainWindow._dataProvider.AllTradesList[i].TradeTime + " " + mainWindow._dataProvider.AllTradesList[i].Quantity + " Сумма=" + candle.Volume, mainWindow.ListBox_Logs);
                                        item.LastNumberDeal = i+1;
                                    }
                                  
                                    if ((candle.TradeDateTime.Date ==
                                        mainWindow._dataProvider.AllTradesList[i].TradeDate.Date &&
                                        (((int)candle.TradeDateTime.TimeOfDay.TotalMinutes <
                                        (int)mainWindow._dataProvider.AllTradesList[i].TradeTime.TimeOfDay.TotalMinutes)
                                        ) ||
                                        (
                                        ((int)candle.TradeDateTime.TimeOfDay.TotalMinutes <
                                        (int)mainWindow._dataProvider.AllTradesList[i].TradeTime.TimeOfDay.TotalMinutes) &&
                                        (candle.TradeDateTime.TimeOfDay.TotalMinutes !=
                                        mainWindow._dataProvider.AllTradesList[i].TradeTime.TimeOfDay.TotalMinutes) &&
                                        mainWindow._dataProvider.AllTradesList[i].TradeTime.TimeOfDay.Seconds == 0
                                        )
                                        ) ||
                                        (candle.TradeDateTime.Date < mainWindow._dataProvider.AllTradesList[i].TradeDate.Date))
                                    {
                                        DateTime tmpDateTime = new DateTime(mainWindow._dataProvider.AllTradesList[i].TradeDate.Year, mainWindow._dataProvider.AllTradesList[i].TradeDate.Date.Month,
                                            mainWindow._dataProvider.AllTradesList[i].TradeDate.Date.Day, mainWindow._dataProvider.AllTradesList[i].TradeTime.Hour, mainWindow._dataProvider.AllTradesList[i].TradeTime.Minute, 00);
                                        //Cfg.SetLog("Добавление новой свечи", mainWindow.ListBox_Logs);
                                       // Cfg.SetLog(mainWindow._dataProvider.AllTradesList[i].TradeNum + " " + mainWindow._dataProvider.AllTradesList[i].TradeTime + " " + mainWindow._dataProvider.AllTradesList[i].Quantity, mainWindow.ListBox_Logs);
                                        item.CandleItems.Add(new CandleItem()
                                        {

                                            TradeDateTime = tmpDateTime,
                                            Open = mainWindow._dataProvider.AllTradesList[i].Price,
                                            Close = mainWindow._dataProvider.AllTradesList[i].Price,
                                            High = mainWindow._dataProvider.AllTradesList[i].Price,
                                            Low = mainWindow._dataProvider.AllTradesList[i].Price,
                                            Volume = mainWindow._dataProvider.AllTradesList[i].Quantity
                                        });
                                        item.LastNumberDeal = i+1;
                                    }
                                }
                                else
                                {
                                    var tmpDateTime = new DateTime(mainWindow._dataProvider.AllTradesList[i].TradeDate.Year, mainWindow._dataProvider.AllTradesList[i].TradeDate.Date.Month,
                                           mainWindow._dataProvider.AllTradesList[i].TradeDate.Date.Day, mainWindow._dataProvider.AllTradesList[i].TradeTime.Hour, mainWindow._dataProvider.AllTradesList[i].TradeTime.Minute, 00);
                                    item.CandleItems.Add(new CandleItem()
                                    {
                                        TradeDateTime = tmpDateTime,
                                        Open = mainWindow._dataProvider.AllTradesList[i].Price,
                                        Close = mainWindow._dataProvider.AllTradesList[i].Price,
                                        High = mainWindow._dataProvider.AllTradesList[i].Price,
                                        Low = mainWindow._dataProvider.AllTradesList[i].Price,
                                        Volume = mainWindow._dataProvider.AllTradesList[i].Quantity
                                    });
                                    item.LastNumberDeal = i+1;
                                }
                        }


                    }
                    #endregion
                }

                foreach (var item in mainWindow._dataProvider.TimeFrameItems)
                {
                    #region работа с другими таймфреймами
                    if (item.TimeFrame > 1 && mainWindow._dataProvider.TimeFrameItems.Where(a => a.Instrument == item.Instrument).Count(a => a.TimeFrame == 1) > 0)
                    {
                        TimeFrameItem candleSmall = new TimeFrameItem();
                        foreach (var item2 in mainWindow._dataProvider.TimeFrameItems)
                        {
                            if (item.Instrument == item2.Instrument && item2.TimeFrame == 1)
                            {
                                candleSmall = item2;
                                break;
                            }
                        }
                        //if (item.CandleItems.Count > 0
                        //int tmpVolume=0;
                        for (int i = 0; i < candleSmall.CandleItems.Count; i++)
                        {



                            if (item.CandleItems.Count > 0)
                            {


                                var candle = item.CandleItems[item.CandleItems.Count-1];
                                //цикл для времени, чтоб считалось все верно, а не по часам и минутам свечей.
                                var tmpTime = candle.TradeDateTime;
                                if (tmpTime.Date == candleSmall.CandleItems[i].TradeDateTime.Date)
                                    while (tmpTime.TimeOfDay.TotalMinutes + item.TimeFrame < candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes
                                        && candle.TradeDateTime.Date == candleSmall.CandleItems[candleSmall.CandleItems.Count - 1].TradeDateTime.Date)
                                    {
                                        tmpTime = tmpTime.Add(TimeConvertor(item.TimeFrame));
                                    }

                                if (candle.TradeDateTime.Date ==
                                    candleSmall.CandleItems[i].TradeDateTime.Date &&
                                    //(int)Math.Abs((candle.TradeDateTime.TimeOfDay).TotalMinutes -candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes) < item.TimeFrame)
                                    (int)(candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes - (candle.TradeDateTime.TimeOfDay).TotalMinutes) < item.TimeFrame &&
                                    (int)(candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes - (candle.TradeDateTime.TimeOfDay).TotalMinutes) >= 0)
                                {
                                    if ((int)Math.Abs((candle.TradeDateTime.TimeOfDay).TotalMinutes -
                                                       candleSmall.CandleItems[i].TradeDateTime.TimeOfDay
                                                           .TotalMinutes) == 0)
                                        candle.Volume = 0;

                                    candle.Close = candleSmall.CandleItems[i].Close;
                                    if (candle.Low > candleSmall.CandleItems[i].Low)
                                        candle.Low = candleSmall.CandleItems[i].Low;
                                    if (candle.High < candleSmall.CandleItems[i].High)
                                        candle.High = candleSmall.CandleItems[i].High;
                                    //tmpVolume = tmpVolume + candleSmall.CandleItems[i].Volume;
                                    //candle.Volume = tmpVolume;
                                    candle.Volume = candle.Volume + candleSmall.CandleItems[i].Volume;
                                }

                                if ((candle.TradeDateTime.Date == candleSmall.CandleItems[i].TradeDateTime.Date &&
                                    (int)Math.Abs((candle.TradeDateTime.TimeOfDay).TotalMinutes -
                                    candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes) >= item.TimeFrame &&
                                    candle.TradeDateTime.TimeOfDay.TotalMinutes < candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes) ||
                                  (candle.TradeDateTime.Date < candleSmall.CandleItems[candleSmall.CandleItems.Count - 1].TradeDateTime.Date &&
                                  candleSmall.CandleItems[i].TradeDateTime.Date == candleSmall.CandleItems[candleSmall.CandleItems.Count - 1].TradeDateTime.Date
                                  ))
                                {
                                    var tmp = candleSmall.CandleItems[i].TradeDateTime;
                                    if (tmpTime.TimeOfDay.Add(TimeConvertor(item.TimeFrame)).TotalMinutes != candleSmall.CandleItems[i].TradeDateTime.TimeOfDay.TotalMinutes
                                        && candle.TradeDateTime.Date == candleSmall.CandleItems[candleSmall.CandleItems.Count - 1].TradeDateTime.Date)
                                        tmp = tmpTime;


                                    item.CandleItems.Add(new CandleItem()
                                    {
                                        TradeDateTime = tmp,
                                        Open = candleSmall.CandleItems[i].Open,
                                        Close = candleSmall.CandleItems[i].Close,
                                        High = candleSmall.CandleItems[i].High,
                                        Low = candleSmall.CandleItems[i].Low,
                                        Volume = candleSmall.CandleItems[i].Volume
                                    });
                                }
                            }
                            else
                            {

                                item.CandleItems.Add(new CandleItem()
                                {
                                    TradeDateTime = candleSmall.CandleItems[i].TradeDateTime,
                                    Open = candleSmall.CandleItems[i].Open,
                                    Close = candleSmall.CandleItems[i].Close,
                                    High = candleSmall.CandleItems[i].High,
                                    Low = candleSmall.CandleItems[i].Low,
                                    Volume = candleSmall.CandleItems[i].Volume
                                });
                            }

                        }

                    }
                    #endregion
                }

                foreach (var item in mainWindow._dataProvider.TimeFrameItems)
                {
                    #region работа с дневками
                    if (item.TimeFrame=="D")
                    if (item.TimeFrame > 1 && mainWindow._dataProvider.TimeFrameItems.Where(a => a.Instrument == item.Instrument).Count(a => a.TimeFrame == 1) > 0)
                    {
                        TimeFrameItem candleSmall = new TimeFrameItem();
                        foreach (var item2 in mainWindow._dataProvider.TimeFrameItems)
                        {
                            if (item.Instrument == item2.Instrument && item2.TimeFrame == 1)
                            {
                                candleSmall = item2;
                                break;
                            }
                        }

                        for (int i = 0; i < candleSmall.CandleItems.Count; i++)
                        {

                            if (item.CandleItems.Count > 0)
                            {
                                var candle = item.CandleItems[item.CandleItems.Count - 1];

                                if (candle.TradeDateTime.Date ==
                                    candleSmall.CandleItems[i].TradeDateTime.Date)
          
                                {
                                    candle.Close = candleSmall.CandleItems[i].Close;
                                    if (candle.Low > candleSmall.CandleItems[i].Low)
                                        candle.Low = candleSmall.CandleItems[i].Low;
                                    if (candle.High < candleSmall.CandleItems[i].High)
                                        candle.High = candleSmall.CandleItems[i].High;
                                    candle.Volume = candle.Volume + candleSmall.CandleItems[i].Volume;
                                }

                                if (candle.TradeDateTime.Date !=
                                    candleSmall.CandleItems[i].TradeDateTime.Date)
                                {
                                    item.CandleItems.Add(new CandleItem()
                                    {
                                        TradeDateTime = candleSmall.CandleItems[i].TradeDateTime,
                                        Open = candleSmall.CandleItems[i].Open,
                                        Close = candleSmall.CandleItems[i].Close,
                                        High = candleSmall.CandleItems[i].High,
                                        Low = candleSmall.CandleItems[i].Low,
                                        Volume = candleSmall.CandleItems[i].Volume
                                    });
                                }
                            }
                            else
                            {

                                item.CandleItems.Add(new CandleItem()
                                {
                                    TradeDateTime = candleSmall.CandleItems[i].TradeDateTime,
                                    Open = candleSmall.CandleItems[i].Open,
                                    Close = candleSmall.CandleItems[i].Close,
                                    High = candleSmall.CandleItems[i].High,
                                    Low = candleSmall.CandleItems[i].Low,
                                    Volume = candleSmall.CandleItems[i].Volume
                                });
                            }

                        }

                    }
                    #endregion
                }
                

            }

        }

        /// <summary>
        /// Преобразование минут в часы
        /// </summary>
        /// <param name="min"></param>
        /// <returns></returns>
        private TimeSpan TimeConvertor(int min)
        {
            int hour = min / 60;
            int minutes = (min - 60 * hour);
            var result = new TimeSpan(hour, minutes, 0);

            return result;
        }
    }


}
